/*
Package KcpServer
author: jamon
time: 2023-09-07
desc:
*/
package KcpServer

import (
	"encoding/binary"
	"fmt"
	"gitee.com/jamon/espoir_go/logger"
	"github.com/xtaci/kcp-go"
	"time"
)

// MsgHeaderLen 消息头长度:    消息内容长度4byte + 消息ID 4byte + 版本号 4byte
const MsgHeaderLen uint32 = 12

const MaxChannelNum = 100000

const HeartTimeout = 60 // 心跳超时时间（秒）

var MsgHandlerFunc map[uint32]func(data []byte) []byte = make(map[uint32]func(data []byte) []byte)

type MsgHeader struct {
	MsgLen  uint32
	MsgId   uint32
	Version uint32
}

func NewMsgHeader(buf []byte) *MsgHeader {
	if len(buf) < int(MsgHeaderLen) {
		logger.Error("NewMsgHeader: invalid buf len", logger.Kwargs{"buf": buf})
		return nil
	}
	msgLen := binary.LittleEndian.Uint32(buf[0:4])
	msgId := binary.LittleEndian.Uint32(buf[4:8])
	version := binary.LittleEndian.Uint32(buf[8:12])

	return &MsgHeader{
		MsgLen:  msgLen,
		MsgId:   msgId,
		Version: version,
	}
}

func RegisterMsgHandler(msgId uint32, f func(data []byte) []byte) {
	MsgHandlerFunc[msgId] = f
}

func GetMsgHandler(msgId uint32) func(data []byte) []byte {
	handler, ok := MsgHandlerFunc[msgId]
	if !ok {
		logger.Error("GetMsgHandler: invalid msgId", logger.Kwargs{"msgId": msgId})
		return nil
	}
	return handler
}

type MsgData struct {
	MsgId   uint32
	RawData []byte
	IsPush  bool
}

type MsgContext struct {
	msgData   *MsgData
	sessionId string
}

func GetSessionId(kcpSession *kcp.UDPSession) string {
	return fmt.Sprintf("%v_%v", kcpSession.RemoteAddr().String(), kcpSession.GetConv())
}

type SessionInfo struct {
	SessionId     string
	Session       *kcp.UDPSession
	IsClosing     bool
	LastHeartTime int32
}

func (s *SessionInfo) Close() {
	if s.IsClosing {
		return
	}
	s.IsClosing = true
	err := s.Session.Close()
	if err != nil {
		return
	}
}

func (s *SessionInfo) UpdateHeartTime() {
	s.LastHeartTime = int32(time.Now().Unix())
}

func (s *SessionInfo) IsHeartTimeout() bool {
	if s.LastHeartTime == 0 {
		return false
	}
	return int32(time.Now().Unix())-s.LastHeartTime > 60
}
